(function (global, factory) {
    if (typeof define === 'function' && define.amd)
      define(function() { return factory(global) })
    else
      factory(global)
})(this, function(window) {
    // 核心模块
    let dom = (function () {
        let $, dom = {}, emptyArray = [], emptyObject = {}, toString = emptyObject.toString;

        // 创建dom对象
        function Z(el, selector) {
            let i, len = el ? el.length : 0
            for (i = 0; i < len; i++) this[i] = el[i]
            this.length = len
            this.selector = selector || ''
        }

        // 获取dom对象
        $ = function (selector) {
            return dom.init(selector)
        }

        // 选择器处理
        dom.init = function(selector) {
            let el
            // 如果selector不存在
            if (!selector) return dom.Z()
            // 如果selector是方法
            else if (isFunction(selector)) return $(document).ready(selector)
            // 如果是dom对象
            else if (dom.isZ(selector)) return selector
            // 其他情况统一用原生选择器获取
            else {
                el = dom.qsa(document, selector)
            }
            return dom.Z(el, selector)
        }

        // 获取Z对象
        dom.Z = function(el, selector) {
            return new Z(el, selector)
        }

        // 是否为dom.Z实例
        dom.isZ = function(object) {
            return object instanceof dom.Z
        }

        // 选择器方法
        dom.qsa = function(element, selector){
            return element.querySelectorAll(selector)
        }

        // 定义dom的原型属性
        $.fn = {
            constructor: dom.Z,
            length: 0,
            // 文档初始化
            ready: function(callback){
                document.addEventListener('DOMContentLoaded', function(e){ callback(e) }, false);
                return this
            },
            // 元素遍历
            each: function(callback){
                emptyArray.every.call(this, function(el, index){
                    return callback.call(el, index, el) !== false
                })
                return this
            },
            // 查找操作(find)
            find: function(selector){
                let els = [];
                this.each(function(){
                    let childs = this.querySelectorAll(selector);
                    els.push(...childs);
                })
                return dom.Z(els, selector);
            },
            // 元素处理
            remove: function(){
                this.each(function(){
                    this.remove();
                })
                return this;
            },
            // 样式操作(addClass/removeClass/hasClass/toggleClass)
            addClass: function(className){
                this.each(function(){
                    this.classList.add(className)
                })
                return this;
            },
            removeClass: function(className){
                this.each(function(){
                    this.classList.remove(className)
                })
                return this;
            },
            hasClass: function(className){
                return emptyArray.every.call(this, function(el){
                    return el.classList.contains(className) !== false
                })
            },
            toggleClass: function(className){
                this.each(function(index, el){
                    el.classList.toggle(className)
                })
                return this;
            },
            // 属性操作(attr/removeAttr)
            attr: function(name, value){
                this.each(function(){
                    this.setAttribute(name, value)
                })
                return this;
            },
            removeAttr: function(name){
                this.each(function(){
                    this.removeAttribute(name)
                })
                return this;
            },
            // 内容操作(html/text/val)
            html: function(html){
                this.each(function(){
                    this.innerHTML = html;
                })
                return this;
            },
            text: function(text){
                this.each(function(){
                    this.textContent = text;
                })
                return this;
            },
            val: function(value){
                this.each(function(){
                    this.value = value;
                })
                return this;
            },
            // 显示操作(show/hide)
            show: function(){
                this.each(function(){
                    this.style.display = 'block';
                })
                return this;
            },
            hide: function(){
                this.each(function(){
                    this.style.display = 'none';
                })
                return this;
            },
        }

        // 串通原型链
        dom.Z.prototype = Z.prototype = $.fn;

        // 赋值dom引用给$
        $.dom = dom;
    
        return $
    })();

    // window上注册dom
    window.dom = dom
    window.$ === undefined && (window.$ = dom)

    // 定义全局方法
    function isFunction(value) { return typeof value == "function" }
    function isWindow(obj)     { return obj != null && obj == obj.window }
    function isDocument(obj)   { return obj != null && obj.nodeType == obj.DOCUMENT_NODE }
    function isType(value) { return toString.call(value).toLowerCase().replace(/(\[object\s)|(\])/g, "") }

    // 定义dom的全局方法
    $.isFunction = isFunction;
    $.isWindow = isWindow;
    $.isDocument = isDocument;
    $.isType = isType;

    // 其它模块省略...
    // event, ajax, animate
})